/**
 * @description 请求数据模块
 * @author Rid King
 * @since 2018-07-06
 */

import Service from '../../../service/2.0.0/js/service'
import {indicator} from '../../../dialoger/2.0.0/js/indicator'
import {ajaxService} from '../../../service/2.0.0/js/ajax-service'
import {storeMemory} from '../../../store/2.0.0/js/store-memory'

/**
 * @class 请求类
*/
class RequesterService extends Service {
  /**
   * @function 构造方法
   * @param {Object} options // 配置
   * {
   *  service // 服务对象
   *  indicator // 预加载器
   *  [store] // 存储器
   * }
  */
  constructor (options) {
    super()
    options = options || {}
    this.service = options.service
    this.indicator = options.indicator
    this.store = options.store
    // 内存存储
    this.storeMemory = storeMemory
  }

  /**
   * @function 发送请求数据
   * @param {Object} options // 配置对象
   * @return {Promise}
  */
  _send (options) {
    let defer = null
    // 是否缓存数据或是否缓冲相同的请求
    defer = this.getCache(options) || this.getBuffer(options)
    // 无数据则发送请求
    if (!defer) {
      defer = this.service._send.apply(this.service, arguments)
      // 缓存数据
      // this.setCache(options, defer)
      // 缓冲请求
      this.setBuffer(options, defer)
    }

    return defer
  }

  /**
   * @function 处理配置参数
   * @return {Object}
   * */
  process () {
    return this.service.process.apply(this.service, arguments)
  }

  /**
   * @function 设置配置
   * @param {Object} options // 配置对象
  */
  setOptions (options) {
    this.service.setOptions(options)
  }

  /**
   * @function 请求前处理
  */
  onBeforeRequest (options) {
    options.isPreloader && this.indicator.show()
  }

  /**
   * @function 请求后处理
  */
  onAfterRequest (result) {
    let options = result.options
    // 缓存数据
    if (options.cache) {
      this.store.setItem(
        this.getCacheKey(options),
        result, options.cache
      )
    }
    options.isPreloader && this.indicator.hide()
  }

  /**
   * @function 获取缓存key
   * @param {Object} options
  */
  getCacheKey (options) {
    return {
      name: 'cache',
      method: options.method,
      url: options.url,
      data: options.data
    }
  }

  /**
   * @function 获取缓存key
   * @param {Object} options
  */
  getCache (options) {
    options = options || {}
    let defer = null
    if (options.cache) {
      let cacheKey = this.getCacheKey(options)
      let data = this.store.getItem(cacheKey)
      if (data !== null && data !== undefined) {
        defer = Promise.resolve(data)
      }
    }

    return defer
  }

  /**
   * @function 设置缓存数据
   * @param {Object} options
  */
  setCache (options, defer) {
    options = options || {}
    if (!options.cache) {
      return false
    }

    // 转对象
    if (typeof options.cache !== 'object') {
      options.cache = {}
    }
    // 缓冲周期设置
    let expires = options.cache.expires
    expires = isNaN(expires) ? 60 * 1000 * 30 : expires
    // 最大缓存180天
    expires = expires > 180 * 24 * 60 * 60 * 1000 ? 60 * 1000 : expires
    // 保存缓冲
    this.storeMemory.setItem(
      this.getCacheKey(options),
      defer, options.cache
    )
  }

  /**
   * @function 获取缓冲key
   * @param {Object} options
  */
  getBufferKey (options) {
    return {
      name: 'buffer',
      method: options.method,
      url: options.url,
      data: options.data
    }
  }

  /**
   * @function 获取缓存key
   * @param {Object} options
  */
  getBuffer (options) {
    options = options || {}
    let defer = null
    if (options.buffer) {
      let bufferKey = this.getBufferKey(options)
      defer = this.storeMemory.getItem(bufferKey) || null
    }

    return defer
  }

  /**
   * @function 设置缓冲值
   * @param {Object} options
  */
  setBuffer (options, defer) {
    options = options || {}
    if (!options.buffer) {
      return false
    }

    // 转对象
    if (typeof options.buffer !== 'object') {
      options.buffer = {}
    }
    // 缓冲周期设置
    let expires = options.buffer.expires
    expires = isNaN(expires) ? 5 * 1000 : expires
    // 最大缓冲1分钟
    expires = expires > 60 * 1000 ? 60 * 1000 : expires
    // 保存缓冲
    this.storeMemory.setItem(
      this.getBufferKey(options),
      defer, options.buffer
    )
  }
}

// 生成默认请求对象
const requester = new RequesterService({
  service: ajaxService,
  indicator,
  store: storeMemory
})

export default RequesterService
export {
  requester
}